home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / src / X11 / wais / x / xwais.c < prev    next >
C/C++ Source or Header  |  1995-05-09  |  12KB  |  456 lines

  1. /* WIDE AREA INFORMATION SERVER SOFTWARE:
  2.    No guarantees or restrictions.  See the readme file for the full standard
  3.    disclaimer.
  4.  
  5.    This is part of the X user-interface for the WAIS software.  Do with it
  6.    as you please.
  7.  
  8.    jonathan@Think.COM
  9.  *
  10.  * $Log:    xwais.c,v $
  11.  * Revision 1.16  92/04/28  15:33:35  jonathan
  12.  * Changed references to directory reading functions to use scandir.
  13.  * 
  14.  * Revision 1.15  92/03/23  16:11:11  jonathan
  15.  * ?
  16.  * 
  17.  * Revision 1.14  92/03/17  14:20:24  jonathan
  18.  * Generally cleaned up.
  19.  * 
  20.  * Revision 1.13  92/03/07  19:39:42  jonathan
  21.  * Fixed argument to ScanDirs.
  22.  * 
  23.  * Revision 1.12  92/03/06  14:48:19  jonathan
  24.  * New and Improved source loading!
  25.  * 
  26.  * Revision 1.11  92/03/05  11:47:09  jonathan
  27.  * Replace directory routines with scandir's.
  28.  * 
  29.  * Revision 1.10  92/03/01  14:03:40  jonathan
  30.  * Added command_name to main.
  31.  * 
  32.  * 
  33. */
  34.  
  35. #ifndef lint
  36. static char *RCSid = "$Header: /tmp_mnt/net/quake/proj/wais/wais-8-b5/x/RCS/xwais.c,v 1.16 92/04/28 15:33:35 jonathan Exp $";
  37. #endif
  38.  
  39. #define MAIN
  40. #define XWAIS_C
  41. #define XWAIS
  42. #include "xwais.h"
  43. #include "xwais.bit"
  44.  
  45. #define offset(field) XtOffset(struct _app_resources*, field)
  46. static XtResource resources[] = {
  47.    {"questionDirectory", "QuestionDirectory", XtRString, sizeof(char *),
  48.          offset(questionDirectory), XtRString, "~/wais-questions/"},
  49.    {"userSourceDirectory", "UserSourceDirectory", XtRString, sizeof(char *),
  50.          offset(userSourceDirectory), XtRString, "~/wais-sources/"},
  51.    {"commonSourceDirectory", "CommonSourceDirectory", XtRString, sizeof(char *),
  52.          offset(commonSourceDirectory), XtRString, ""},
  53.    {"documentDirectory", "DocumentDirectory", XtRString, sizeof(char *),
  54.          offset(documentDirectory), XtRString, "~/wais-documents/"},
  55.    {"helpFile", "HelpFile", XtRString, sizeof(char *),
  56.          offset(helpFile), XtRString, "./XwaisHELP"},
  57.    {"removeSeekerCodes", "RemoveSeekerCodes", XtRString, sizeof(char *),
  58.       offset(removeSeekerCodes), XtRString, "On"},
  59.    {"rescanInterval", "RescanInterval", XtRString, sizeof(char *),
  60.       offset(rescanInterval), XtRString, "1"},
  61.    {"seedWords", "SeedWords", XtRString, sizeof(char *),
  62.       offset(seedWords), XtRString, ""},
  63.    {"initialSource", "initialSource", XtRString, sizeof(char *),
  64.       offset(initialSource), XtRString, ""},
  65.    {"questionName", "QuestionName", XtRString, sizeof(char *),
  66.       offset(questionName), XtRString, ""},
  67.    {"filters", "Filters", XtRString, sizeof(char *),
  68.       offset(filters), XtRString, ""},
  69.    {"doSearch", "DoSearch", XtRBoolean, sizeof(Boolean),
  70.       offset(doSearch), XtRBoolean, False},
  71.    {"defaultsInstalled", "DefaultsInstalled",  XtRBoolean, sizeof(Boolean),
  72.       offset(defaultsInstalled), XtRBoolean, False}
  73. };
  74. #undef offset
  75.  
  76. void SetIcon(parent)
  77. Widget parent;
  78. {
  79.   Arg args[1];
  80.   Pixmap icon_pixmap = None;
  81.  
  82.   XtSetArg (args[0], XtNiconPixmap, &icon_pixmap);
  83.   XtGetValues(parent, args, ONE);
  84.   if (icon_pixmap == None) {
  85.     XtSetArg(args[0], XtNiconPixmap, 
  86.          XCreateBitmapFromData(XtDisplay(parent),
  87.                    XtScreen(parent)->root,
  88.                    xwais_bits, xwais_width, xwais_height));
  89.     XtSetValues (parent, args, ONE);
  90.   }
  91. }
  92.  
  93. static quit;
  94.  
  95. static int
  96. my_alphasort(d1, d2)
  97.     struct dirent **d1;
  98.     struct dirent **d2;
  99. {
  100.     return strcasecmp(d1[0]->d_name, d2[0]->d_name);
  101. }
  102.  
  103. static int
  104. isqfile(dp)
  105. struct dirent *dp;
  106. {
  107.   char lastchar = dp->d_name[strlen(dp->d_name)-1];
  108.   return(lastchar != '~' && lastchar != '#' &&
  109.       strcmp(dp->d_name, ".") && strcmp(dp->d_name, ".."));
  110. }
  111.  
  112. void
  113. ReadQuestionDirectory(directory)
  114. char *directory;
  115. {
  116.   struct dirent **list;
  117.   char filename[MAX_FILENAME_LEN], lastchar;
  118.   FILE *fp;
  119.   char config[STRINGSIZE];
  120.   int i, j;
  121.   float shown;
  122.  
  123.   if ((j = scandir(directory, &list, isqfile, my_alphasort)) < 0)
  124.     {
  125.       char booboo[STRINGSIZE];
  126.       sprintf(booboo, "Error on open of questions directory: %s.\n", directory);
  127.       XwaisPrintf(booboo);
  128.       return;
  129.     }
  130.  
  131.   if(Question_items != NULL) {
  132.     for(i =0; Question_items[i] != NULL; i++) s_free(Question_items[i]);
  133.     s_free(Question_items);
  134.   }
  135.  
  136.   Question_items = (char**) s_malloc((j+1) * sizeof(char*));
  137.  
  138.   for (i = 0; i < j; i++) {
  139.     Question_items[i] = s_strdup(list[i]->d_name);
  140.     s_free(list[i]);
  141.   }
  142.  
  143.   NumQuestions = j;
  144.   s_free(list);
  145. }
  146.  
  147. static time_t usersourcetime, commonsourcetime, questiontime;
  148. static int rescanint;
  149.  
  150. void ScanDirs(closure, id)
  151.      Opaque closure;
  152.      XtIntervalId *id;
  153. {
  154.   char **list_data;
  155.   float top, shown;
  156.   int CurrentQuestion, CurrentSource, i;
  157.   struct stat buf;
  158.   boolean rescan;
  159.   char string[STRINGSIZE];
  160.  
  161.   rescan = FALSE;
  162.  
  163.   stat(app_resources.userSourceDirectory, &buf);
  164.  
  165.   if(buf.st_mtime != usersourcetime) {
  166.     usersourcetime = buf.st_mtime;
  167.     rescan = TRUE;
  168.   }
  169.  
  170.   if(app_resources.commonSourceDirectory[0] != 0) {
  171.     stat(app_resources.commonSourceDirectory, &buf);
  172.  
  173.     if(buf.st_mtime != commonsourcetime) {
  174.       commonsourcetime = buf.st_mtime;
  175.       rescan = TRUE;
  176.     }
  177.   }
  178.  
  179.   if (rescan) {
  180.     rescan = FALSE;
  181.  
  182.     CurrentSource = get_selected_source();
  183.     if (CurrentSource != NO_ITEM_SELECTED)
  184.       strcpy(string, Source_items[CurrentSource]);
  185.  
  186.     NumSources = 0;
  187.  
  188.     GetSourceNames(app_resources.userSourceDirectory);
  189.     if(app_resources.commonSourceDirectory[0] != 0)
  190.       GetSourceNames(app_resources.commonSourceDirectory);
  191.  
  192.     RebuildListWidget(sourcewindow, Source_items);
  193.  
  194.     if(CurrentSource != NO_ITEM_SELECTED) {
  195.       for(i = 0;
  196.       Source_items[i] != NULL && 
  197.       strcmp(Source_items[i], string) != 0;
  198.       i++);
  199.       if(i < NumSources) XawListHighlight(sourcewindow->ListWidget, i);
  200.     }
  201.   }
  202.  
  203.   stat(app_resources.questionDirectory, &buf);
  204.  
  205.   if(buf.st_mtime != questiontime) {
  206.     questiontime = buf.st_mtime;
  207.     rescan = TRUE;
  208.   }
  209.  
  210.   if (rescan) {
  211.     NumQuestions = 0;
  212.  
  213.     CurrentQuestion = get_selected_question();
  214.  
  215.     if (CurrentQuestion != NO_ITEM_SELECTED)
  216.       strcpy(string, Question_items[CurrentQuestion]);
  217.  
  218.     ReadQuestionDirectory(app_resources.questionDirectory);
  219.     Question_items[NumQuestions] = NULL;
  220.  
  221.     RebuildListWidget(questionwindow, Question_items);
  222.  
  223.     if(CurrentQuestion != NO_ITEM_SELECTED) {
  224.       for(i = 0;
  225.       Question_items[i] != NULL &&
  226.       strcmp(Question_items[i], string) != 0;
  227.       i++);
  228.       if(i < NumQuestions) XawListHighlight(questionwindow->ListWidget, i);
  229.     }
  230.   }
  231.  
  232.   rescantimerid = XtAddTimeOut(rescanint, ScanDirs, (Opaque) ScanDirs);
  233. }
  234.  
  235. void ExitCommand()
  236. {
  237.   exit(-1);
  238. }
  239.  
  240. PopExit(parent, message)
  241. Widget parent;
  242. char *message;
  243. {
  244.   Widget shell, frame, labelwid, stringlabelwid;
  245.   WidgetClass wclass;
  246.   static String namestring;
  247.   Arg        args[5];
  248.   Position    x, y;
  249.   Dimension    width, height;
  250.   Cardinal    n;
  251.  
  252.   shell = XtCreatePopupShell("exitpopup", applicationShellWidgetClass,
  253.                  parent, NULL, ZERO);
  254.   frame = XtCreateManagedWidget("exitpopupform", formWidgetClass,
  255.                 shell, NULL, ZERO);
  256.  
  257.   labelwid = MakeLabel(frame, "exitlabel", message, NULL, NULL);
  258.  
  259.   MakeCommandButton(frame, "Ok", ExitCommand, labelwid, NULL, NULL);
  260.  
  261.   n = 0;
  262.   XtSetArg(args[n], XtNx, 100); n++;
  263.   XtSetArg(args[n], XtNy, 100); n++;
  264.   XtSetArg(args[n], XtNtitle, "XWAIS Error"); n++;
  265.   XtSetValues(shell, args, n);
  266.  
  267.   XtPopup(shell, XtGrabExclusive);
  268. }
  269.  
  270.  
  271. char *log_file_name = NULL;
  272. FILE *logfile = NULL;
  273.  
  274. void
  275. main(argc, argv)
  276.      int argc;
  277.      char *argv[];
  278. {
  279.   struct stat buf;
  280.   long first_filename_number = 1; /* for indexing into the arglist */
  281.   long count;
  282.  
  283.   if (command_name = (char*)rindex(argv[0], '/'))
  284.     command_name++;
  285.   else
  286.     command_name = argv[0];
  287.  
  288.   NumSources = 0;
  289.  
  290.   double_click = FALSE;
  291.  
  292.   top = XtInitialize( "xwais", "Xwais", NULL, 0, &argc, argv);
  293.   
  294.   XtGetApplicationResources(top, &app_resources, resources,
  295.                 XtNumber(resources), NULL, 0);
  296.  
  297.   {
  298.     Arg        args[5];
  299.     Cardinal    n;
  300.  
  301.     n = 0;
  302.     XtSetArg(args[n], XtNtitle, "XWAIS"); n++;
  303.     XtSetArg(args[n], XtNiconName, "XWAIS"); n++;
  304.     XtSetValues(top, args, n);
  305.   }
  306.  
  307.   SetIcon(top);
  308.  
  309.   if (app_resources.defaultsInstalled == False) {
  310.     PopExit(top, "X resources not properly installed");
  311.     XtMainLoop();
  312.   }
  313.  
  314.   CurDpy = XtDisplay(top);
  315.  
  316.   form = SetupWaisDisplay(top);
  317.  
  318.   if(app_resources.documentDirectory[0] == '~') {
  319.     char *home, *dir, *getenv();
  320.     
  321.     if((home = getenv("HOME")) != NULL) {
  322.       if((dir = s_malloc(strlen(home) +
  323.                strlen(app_resources.documentDirectory) +
  324.                2)) == NULL) {
  325.     fprintf(stderr, "Ran out of space trying to create directory name.\n");
  326.     exit(-1);
  327.       }
  328.       strcpy(dir, home);
  329.       strcat(dir, &app_resources.documentDirectory[1]);
  330.       app_resources.documentDirectory=dir;
  331.     }
  332.   }
  333.  
  334.   if(app_resources.userSourceDirectory[0] == '~') {
  335.     char *home, *dir, *getenv();
  336.     
  337.     if((home = getenv("HOME")) != NULL) {
  338.       if((dir = s_malloc(strlen(home) +
  339.                strlen(app_resources.userSourceDirectory) +
  340.                2)) == NULL) {
  341.     fprintf(stderr, "Ran out of space trying to create directory name.\n");
  342.     exit(-1);
  343.       }
  344.       strcpy(dir, home);
  345.       strcat(dir, &app_resources.userSourceDirectory[1]);
  346.       app_resources.userSourceDirectory=dir;
  347.     }
  348.   }
  349.   sdir = app_resources.userSourceDirectory;
  350.   cdir = app_resources.commonSourceDirectory;
  351.  
  352.   if(app_resources.questionDirectory[0] == '~') {
  353.     char *home, *dir, *getenv();
  354.     
  355.     if((home = getenv("HOME")) != NULL) {
  356.       if((dir = s_malloc(strlen(home) +
  357.                strlen(app_resources.questionDirectory) +
  358.                2)) == NULL) {
  359.     fprintf(stderr, "Ran out of space trying to create directory name.\n");
  360.     exit(-1);
  361.       }
  362.       strcpy(dir, home);
  363.       strcat(dir, &app_resources.questionDirectory[1]);
  364.       app_resources.questionDirectory=dir;
  365.     }
  366.   }
  367.  
  368.   /* let's see if user directories exist, if not, try to create them */
  369.   {
  370.     DIR *dirp;
  371.     char *makedir;
  372.  
  373.     if((dirp = opendir(app_resources.questionDirectory)) == NULL) {
  374.       if((makedir = s_malloc(strlen(app_resources.questionDirectory) + 12))
  375.      == NULL) {
  376.     fprintf(stderr, "Ran out of space trying to create directory name.\n");
  377.     exit(-1);
  378.       }
  379.       strcpy(makedir, "/bin/mkdir ");
  380.       strcat(makedir, app_resources.questionDirectory);
  381.       if(makedir[strlen(makedir)-1] == '/') makedir[strlen(makedir)-1] = 0;
  382.       if(system(makedir) != 0)
  383.     fprintf(stderr, "Error creating directory: %s\n",
  384.         app_resources.questionDirectory);
  385.     }
  386.     else
  387.       closedir(dirp);
  388.  
  389.     if((dirp = opendir(app_resources.userSourceDirectory)) == NULL) {
  390.       if((makedir = s_malloc(strlen(app_resources.userSourceDirectory) + 12))
  391.      == NULL) {
  392.     fprintf(stderr, "Ran out of space trying to create directory name.\n");
  393.     exit(-1);
  394.       }
  395.       strcpy(makedir, "/bin/mkdir ");
  396.       strcat(makedir, app_resources.userSourceDirectory);
  397.       if(makedir[strlen(makedir)-1] == '/') makedir[strlen(makedir)-1] = 0;
  398.       if(system(makedir) != 0)
  399.     fprintf(stderr, "Error creating directory: %s\n",
  400.         app_resources.userSourceDirectory);
  401.     }
  402.     else
  403.       closedir(dirp);
  404.   }
  405.   
  406.   stat(app_resources.userSourceDirectory, &buf);
  407.   usersourcetime = buf.st_mtime;
  408.   GetSourceNames(app_resources.userSourceDirectory);
  409.  
  410.   if(app_resources.commonSourceDirectory[0] != 0) {
  411.     stat(app_resources.commonSourceDirectory, &buf);
  412.     commonsourcetime = buf.st_mtime;
  413.     GetSourceNames(app_resources.commonSourceDirectory);
  414.   }
  415.  
  416.   stat(app_resources.questionDirectory, &buf);
  417.   questiontime = buf.st_mtime;
  418.   ReadQuestionDirectory(app_resources.questionDirectory);
  419.  
  420.   Question_items[NumQuestions] = NULL;
  421.  
  422.   RebuildListWidget(questionwindow, Question_items);
  423.  
  424.   RebuildListWidget(sourcewindow, Source_items);
  425.  
  426.   /* and away we go! */
  427.  
  428.   rescanint = 1000 * atoi(app_resources.rescanInterval);
  429.  
  430.   rescantimerid = XtAddTimeOut(rescanint, ScanDirs, (Opaque) ScanDirs);
  431.  
  432.   XtRealizeWidget(top);
  433.  
  434.   XtMainLoop();
  435. }
  436.  
  437. /* ARGSUSED */
  438. void
  439. DoQuit(w, closure, call_data)
  440. Widget w;
  441. XtPointer closure, call_data;
  442. {
  443.   char msg[STRINGSIZE], quest[STRINGSIZE];
  444.  
  445.   if(double_click && LastClicked == w) {
  446.     exit(0); 
  447.   }
  448.  
  449.   msg[0] = 0;
  450.  
  451.   XwaisPrintf("If you really want to quit, press Quit again.\n");
  452.   Feep();
  453.   double_click = TRUE;
  454.   LastClicked = w;
  455. }
  456.